﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

using MonPocGarage.ArmyContracts;
using MonPocGarage.ArmyContracts.Common;
using MonPocGarage.ArmyContracts.Common.Abilities;
using MonPocGarage.ArmyContracts.Common.Enums;
using MonPocGarage.Common.Extensions;
using MonPocGarage.Common.Logging;

namespace MonPocGarage.ArmyData.Builders
{
    internal static class BuildUnitList
    {
        internal static List<Unit> Build()
        {
            List<Unit> units = new List<Unit>();
            List<IAbility> abilities = BuildAbilityList.GetAbilityList();
            XmlDocument xDoc = new XmlDocument();
            try
            {
                foreach (string file in Directory.EnumerateFiles(Environment.CurrentDirectory + "/Data/Units"))
                {
                    xDoc.Load(file);
                    foreach (XmlNode xNode in xDoc.SelectNodes("Units/Unit"))
                    {
                        Unit mappedUnit = new Unit
                                            {
                                                UnitName = xNode.SelectSingleNode("Name").InnerText,
                                                Agenda = xNode.SelectSingleNode("Agenda").InnerText.ToEnumValue<Agenda>(),
                                                EnergyType = xNode.SelectSingleNode("EnergyType").InnerText.ToEnumValue<EnergyType>(),
                                                Faction = xNode.SelectSingleNode("Faction").InnerText.ToEnumValue<Faction>(),
                                                UnitType = xNode.SelectSingleNode("UnitType").InnerText.ToEnumValue<UnitType>(),
                                                UnitCost = Convert.ToInt32(xNode.SelectSingleNode("UnitCost").InnerText),
                                                Stats = new StatBlock
                                                {
                                                    Blast = Mappers.MapBlastStat(xNode.SelectSingleNode("Stats/Blast")),
                                                    Brawl = Mappers.MapBrawlStat(xNode.SelectSingleNode("Stats/Brawl")),
                                                    Defense = Convert.ToInt32(xNode.SelectSingleNode("Stats/Defense").InnerText),
                                                    Speed = Convert.ToInt32(xNode.SelectSingleNode("Stats/Speed").InnerText)
                                                },
                                                Abilities = new List<IAbility>()
                                            };
                        foreach (XmlNode ability in xNode.SelectNodes("Abilities/Ability/AbilityID"))
                        {
                            IAbility mappedAbility = abilities.Where(a => a.AbilityID == ability.InnerText).FirstOrDefault();
                            if (ability.Attributes["color"] != null)
                            {
                                mappedAbility.ChangeColor(ability.Attributes["color"].Value.ToEnumValue<AbilityColor>());
                            }
                            if (ability.NextSibling != null && mappedAbility.AbilityType == AbilityType.Trigger)
                            {
                                ((Trigger)mappedAbility).ChangeAttackType(ability.NextSibling.InnerText.ToEnumValue<AttackType>());
                            }
                            mappedUnit.Abilities.Add((IAbility)mappedAbility.Clone());
                        }
                        units.Add((Unit)mappedUnit.Clone());
                    }
                }
            }
            catch (Exception ex)
            {
                LogHandler.LogException("Unable to parse a Unit", ex, MessageLevel.ERROR);
            }
            return units;
        }
    }
}
